﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ThermalEquipmentDesign.Model.Condenser.SprinklerR717
{
    class SprinklerR717Model
    {
        SprinklerR717Result res = new SprinklerR717Result();
        SprinklerR717 condenser;

        /// <summary>
        /// Calculate Sprinkler Condenser
        /// </summary>
        /// <param name="con">SprinklerR717 object</param>
        /// <returns>SprinklerR717Result object</returns>
        public SprinklerR717Result ImplementCalculation(SprinklerR717 con)
        {
            condenser = con;
            res.dbHeatCapacity = CalculateHeatCapacity();
            res.dbAverageWaterTemp = CalculateAverageWaterTemp();
            res.dbOutWaterTemp = CalculateOutWaterTemp();
            res.dbPoolWaterTemp = CalculatePoolWaterTemp();
            res.dbCondensationTemp = CalculateCondensationTemp();
            res.dbSolventHeatCoefficient = CalculateSolventHeatCoefficient();
            res.dbSolventHeatDensity = CalculateSolventHeatDensity();
            res.dbWaterThickness = CalculateWaterThickness();
            res.dbWaterSpeed = CalculateWaterSpeed();
            res.dbDeterminedSize = CalculateDeterminedSize();
            res.dbReCoefficient = CalculateReCoefficient();
            res.dbNusseltCoefficient = CalculateNusseltCoefficient();
            res.dbWaterHeatCoefficient = CalculateWaterHeatCoefficient();
            res.dbWaterheatDensity = CalculateWaterheatDensity();
            res.dbInterTransferArea = CalculateInterTransferArea();
            res.dbExterTransferArea = CalculateExterTransferArea();
            res.dbDischargeCoefficient = CalculateDischargeCoefficient();
            res.dbAirHeatTransfer = CalculateAirHeatTransfer();
            res.dbEvaporateQuantity = CalculateEvaporateQuantity();
            res.dbEvaporateCalorie = CalculateEvaporateCalorie();
            res.dbAbsorptionCalorie = CalculateAbsorptionCalorie();
            res.dbWaterEquipmentConsumption = CalculateWaterEquipmentConsumption();
            res.dbWaterRatio = CalculateWaterRatio();
            res.dbAddWaterDischarge = CalculateAddWaterDischarge();
            res.dbWastWaterDischarge = CalculateWastWaterDischarge();
            res.dbUnit = CalculateUnit();
            res.dbPipeLenght = CalculatePipeLenght();
            res.dbHeatTransferArea = CalculateHeatTransferArea();
            res.dbTotalPipeLenght = CalculateTotalPipeLenght();
            res.dbPipeNumber = CalculatePipeNumber();
            res.dbPipeArea = CalculatePipeArea();
            res.dbPipeHeigh = CalculatePipeHeigh();
            return res;
        }

        /// <summary>
        /// Calculate heat capacity
        /// </summary>
        /// <returns>heat capacity</returns>
        private double CalculateHeatCapacity()
        {
            double Qk = 1.2 * condenser.dbColdProductivity;
            return Math.Round(Qk,2);
        }

        /// <summary>
        /// Calculate average temperature of water
        /// </summary>
        /// <returns>average temperature of water</returns>
        private double CalculateAverageWaterTemp()
        {
            double ttb = condenser.dbLimitTemp + 5;
            return ttb;
        }

        /// <summary>
        /// Calculate temperature of sprayed water
        /// </summary>
        /// <returns>temperature of sprayed water</returns>
        private double CalculateOutWaterTemp()
        {
            double t1 = res.dbAverageWaterTemp - 0.5 * condenser.dbDegreeIncreaseTemp;
            return t1;
        }

        /// <summary>
        /// Calculate temperature of water in the pool
        /// </summary>
        /// <returns>temperature of water in the pool</returns>
        private double CalculatePoolWaterTemp()
        {
            double t2 = res.dbAverageWaterTemp + 0.5 * condenser.dbDegreeIncreaseTemp;
            return t2;
        }

        /// <summary>
        /// Calculate condensation temperature
        /// </summary>
        /// <returns>condensation temperature</returns>
        private double CalculateCondensationTemp()
        {
            double e = Math.Pow(Math.E, condenser.dbDegreeIncreaseTemp / condenser.dbLogaritDiffTemp);
            double tk = (res.dbPoolWaterTemp * e - res.dbOutWaterTemp) / (e - 1);
            return Math.Round(tk, 1);
        }

        /// <summary>
        /// Calculate calorific coefficient to solvent
        /// </summary>
        /// <returns>calorific coefficient to solvent</returns>
        private double CalculateSolventHeatCoefficient()
        {
            double alpha = 2100 * Math.Pow(condenser.dbLogaritDiffTemp, -0.167) * Math.Pow(condenser.dbExterDiameter, -0.25);
            return Math.Round(alpha,2);
        }

        /// <summary>
        /// Calculate heat density to solvent
        /// </summary>
        /// <returns>heat density to solvent</returns>
        private double CalculateSolventHeatDensity()
        {
            double q2 = res.dbSolventHeatCoefficient * condenser.dbDiffTemp;
            return Math.Round(q2,2);
        }

        /// <summary>
        /// Calculate thickness of water
        /// </summary>
        /// <returns>thickness of water</returns>
        private double CalculateWaterThickness()
        {
            double can = condenser.dbKinematicViscosity * condenser.dbWaterExpenditure / (9.8 * Math.Pow(condenser.dbDensity, 2));
            double can3 = Math.Pow(can, 1.0 / 3.0);
            double Thick = 1.94 * can3;
            return Math.Round(Thick,6);
        }

        /// <summary>
        /// Calculate average speed of water
        /// </summary>
        /// <returns>average speed of water</returns>
        private double CalculateWaterSpeed()
        {
            double Speed = condenser.dbWaterExpenditure / (condenser.dbDensity * res.dbWaterThickness);
            return Math.Round(Speed,2);
        }

        /// <summary>
        /// Calculate determined size
        /// </summary>
        /// <returns>determined size</returns>
        private double CalculateDeterminedSize()
        {
            double d = 4 * res.dbWaterThickness;
            return Math.Round(d,5);
        }

        /// <summary>
        /// Calculate Reynold coefficient
        /// </summary>
        /// <returns>Reynold coefficient</returns>
        private double CalculateReCoefficient()
        {
            double Re = res.dbWaterSpeed * res.dbDeterminedSize / condenser.dbDynamicViscosity;
            return Math.Round(Re,2);
        }

        /// <summary>
        /// Calculate Nusselt coefficient
        /// </summary>
        /// <returns>Nusselt coefficient</returns>
        private double CalculateNusseltCoefficient()
        {
            double Nu = 0.1 * Math.Pow(res.dbReCoefficient, 0.63) * Math.Pow(condenser.dbPrandtlCoefficient, 0.48);
            return Math.Round(Nu,2);
        }

        /// <summary>
        /// Calculate calorific coefficient to water
        /// </summary>
        /// <returns>calorific coefficient to water</returns>
        private double CalculateWaterHeatCoefficient()
        {
            double alpha = res.dbNusseltCoefficient * condenser.dbHeatTransferCoefficient / res.dbDeterminedSize;
            return Math.Round(alpha,2);
        }

        /// <summary>
        /// Calculate heat density to water
        /// </summary>
        /// <returns>heat density to water</returns>
        private double CalculateWaterheatDensity()
        {
            double q1 = (condenser.dbLogaritDiffTemp - condenser.dbDiffTemp) / ((1 / res.dbWaterHeatCoefficient) + condenser.dbThermalResistance);
            return Math.Round(q1,2);
        }

        /// <summary>
        /// Calculate area of internal surface 
        /// </summary>
        /// <returns>area of internal surface </returns>
        private double CalculateInterTransferArea()
        {
            double F2 = res.dbHeatCapacity * Math.Pow(10,3) / res.dbWaterheatDensity;
            return Math.Round(F2,2);
        }

        /// <summary>
        /// Calculate area of external surface
        /// </summary>
        /// <returns>area of external surface</returns>
        private double CalculateExterTransferArea()
        {
            double F1 = res.dbInterTransferArea * condenser.dbExterDiameter / condenser.dbInterDiameter;
            return Math.Round(F1,2);
        }

        /// <summary>
        /// Calculate discharge coefficient
        /// </summary>
        /// <returns>discharge coefficient</returns>
        private double CalculateDischargeCoefficient()
        {
            double flow = condenser.dbCalorificCoefficient / condenser.dbAverageAirThermalCapacity;
            return Math.Round(flow,2);
        }

        /// <summary>
        /// Calculate amount of transfered heat
        /// </summary>
        /// <returns>amount of transfered heat</returns>
        private double CalculateAirHeatTransfer()
        {
            double Qkk = res.dbExterTransferArea*res.dbDischargeCoefficient*condenser.dbEvaporationCoefficient*(condenser.dbAverageEnthalpy-condenser.dbEnthalpy);
            return Math.Round(Qkk,2);
        }

        /// <summary>
        /// Calculate amount of evaporatived water
        /// </summary>
        /// <returns>amount of evaporatived water</returns>
        private double CalculateEvaporateQuantity()
        {
            double Mb = res.dbExterTransferArea*res.dbDischargeCoefficient*condenser.dbEvaporationCoefficient*(condenser.dbAverageHumidityContent-condenser.dbHumidityContent);
            return Math.Round(Mb,2);
        }

        /// <summary>
        /// Calculate evaporate calorie
        /// </summary>
        /// <returns>evaporate calorie</returns>
        private double CalculateEvaporateCalorie()
        {
            double Qbh = res.dbEvaporateQuantity * condenser.dbAverageWaterThermalCapacity * res.dbPoolWaterTemp;
            return Math.Round(Qbh,2);
        }

        /// <summary>
        /// Calculate absorption calorie
        /// </summary>
        /// <returns>absorption calorie</returns>
        private double CalculateAbsorptionCalorie()
        {
            double Q = res.dbHeatCapacity - res.dbAirHeatTransfer - res.dbEvaporateCalorie;
            return Math.Round(Q,2);
        }

        /// <summary>
        /// Calculate consumption of water
        /// </summary>
        /// <returns>consumption of water</returns>
        private double CalculateWaterEquipmentConsumption()
        {
            double M = res.dbAbsorptionCalorie/(condenser.dbAverageWaterThermalCapacity*condenser.dbDegreeIncreaseTemp);
            return Math.Round(M,2);
        }

        /// <summary>
        /// Calculate ratio between additional water and sprayed water
        /// </summary>
        /// <returns>ratio between additional water and sprayed water</returns>
        private double CalculateWaterRatio()
        {
            double ratio = condenser.dbDegreeIncreaseTemp/(res.dbPoolWaterTemp-condenser.dbWaterTemperature);
            return Math.Round(ratio,2);
        }

        /// <summary>
        /// Calculate additaional water discharge
        /// </summary>
        /// <returns>additaional water discharge</returns>
        private double CalculateAddWaterDischarge()
        {
            double Mbs = res.dbWaterRatio * res.dbWaterEquipmentConsumption;
            return Math.Round(Mbs,2);
        }

        /// <summary>
        /// Calculate wast water discharge
        /// </summary>
        /// <returns>wast water discharge</returns>
        private double CalculateWastWaterDischarge()
        {
            double Mt = res.dbAddWaterDischarge - res.dbEvaporateQuantity;
            return Math.Round(Mt,2);
        }

        /// <summary>
        /// Calculate unit
        /// </summary>
        /// <returns>unit</returns>
        private double CalculateUnit()
        {
            return 7;
        }

        /// <summary>
        /// Calculate lenght of each pipe
        /// </summary>
        /// <returns>lenght of each pipe</returns>
        private double CalculatePipeLenght()
        {
            double l = res.dbWaterEquipmentConsumption/(2*res.dbUnit*condenser.dbWaterExpenditure);
            return Math.Round(l,2);
        }

        /// <summary>
        /// Calculate heat transfer surface of an unit
        /// </summary>
        /// <returns>heat transfer surface of an unit</returns>
        private double CalculateHeatTransferArea()
        {
            double Fd1 = res.dbExterTransferArea / res.dbUnit;
            return Math.Round(Fd1,2);
        }

        /// <summary>
        /// Calculate total lenght of pipe for an unit
        /// </summary>
        /// <returns>total lenght of pipe for an unit</returns>
        private double CalculateTotalPipeLenght()
        {
            double L = res.dbHeatTransferArea/(3.14*condenser.dbExterDiameter);
            return Math.Round(L,2);
        }

        /// <summary>
        /// Calculate number of pipe for an unit
        /// </summary>
        /// <returns>number of pipe for an unit</returns>
        private double CalculatePipeNumber()
        {
            double n = res.dbTotalPipeLenght / res.dbPipeLenght;
            return Math.Round(n,0);
        }

        /// <summary>
        /// Calculate fin pitch
        /// </summary>
        /// <returns>fin pitch</returns>
        private double CalculatePipeArea()
        {
            double S = 1.7 * condenser.dbExterDiameter;
            return Math.Round(S,2);
        }

        /// <summary>
        /// Calculate heigh of pipe
        /// </summary>
        /// <returns>heigh of pipe</returns>
        private double CalculatePipeHeigh()
        {
            double h = (res.dbPipeNumber - 1) * res.dbPipeArea + condenser.dbExterDiameter;
            return Math.Round(h,2);
        }
    }
}
